/*
    Project:        Home Power Control
    File:           HPCSensors.h
    Author:         christian@karunamusic.at
    Date:           02.2015
    Description:    Sensors for the server.
                    Actually they do nothing - get its value from the clients over a tcp-socket.
 */

#ifndef HPCSENSORS_H
#define HPCSENSORS_H

#include <HPCSensor.h>

class HPCButton : public HPCSensor
{
    Q_OBJECT
public:
    /** \brief Constructor
     *
     * \param name name of the sensor.
     * \param id database id of the sensor.
     * \param pin GPIO pin number.
     */
    explicit HPCButton( const QString& name, quint32 id, quint8 pin )
        : HPCSensor(TSensorType::HPCButton,name,id,pin) {}
    /** \brief Destructor.
     */
    virtual ~HPCButton() {}
};

QDataStream& operator<< ( QDataStream& os, HPCButton& s );

class HPCAnemometer : public HPCSensor
{
    Q_OBJECT
public:
    /** \brief Constructor
     *
     * \param name name of the sensor.
     * \param id database id of the sensor.
     * \param pin GPIO pin number.
     * \param interval time (in seconds) to pause between querying the sensor.
     */
    explicit HPCAnemometer( const QString& name, quint32 id, quint8 pin,quint16 interval  )
        : HPCSensor(TSensorType::HPCAnemometer,name,id,pin), m_Interval(interval) {}
    /** \brief Destructor.
     */
    virtual ~HPCAnemometer() {}

    /** Get the interval time to count the ticks from the sensor.
     *
     * \return interval time in seconds.
     */
    inline quint16 Interval()
        { return m_Interval; }

    /** \brief Get the speed of wind in beaufort.
     *
     * \return Speed of wind in beaufort.
     */
    unsigned int Beaufort();

    /** \brief Get class with content as printable string.
     *
     * \return string
     */
    QString asString() const;

private:
    quint16 m_Interval;
};

QDataStream& operator<< ( QDataStream& os, HPCAnemometer& s );

class HPCHumidity22 : public HPCSensor
{
    Q_OBJECT
public:
    /** \brief Constructor
     *
     * \param name name of the sensor.
     * \param id database id of the sensor.
     * \param pin Inputpin.
     */
    explicit HPCHumidity22( const QString& name, quint32 id, quint8 pin )
        : HPCSensor(TSensorType::HPCHumidity22,name,id,pin) {}
    /** \brief Destructor.
     */
    virtual ~HPCHumidity22() {}
};

QDataStream& operator<< ( QDataStream& os, HPCHumidity22& s );

class HPCTemperature22 : public HPCSensor
{
    Q_OBJECT
public:
    /** \brief Constructor
     *
     * \param name name of the sensor.
     * \param id database id of the sensor.
     * \param i2caddr the address on the i2c-bus.
     */
    explicit HPCTemperature22( const QString& name, quint32 id, quint8 i2caddr )
        :HPCSensor(TSensorType::HPCTemperature22,name,id,i2caddr) {}
    /** \brief Destructor.
     */
    virtual ~HPCTemperature22() {}
};

QDataStream& operator<< ( QDataStream& os, HPCTemperature22& s );

class HPCLight : public HPCSensor
{
    Q_OBJECT
public:
    /** \brief Constructor
     *
     * \param name name of the sensor.
     * \param id database id of the sensor.
     * \param i2caddr the address on the i2c-bus.
     */
    explicit HPCLight( const QString& name, quint32 id, quint8 i2caddr )
        : HPCSensor(TSensorType::HPCLight,name,id,i2caddr) {}
    /** \brief Destructor.
     */
    virtual ~HPCLight() {}
};

QDataStream& operator<< ( QDataStream& os, HPCLight& s );

class HPCRainGauge : public HPCSensor
{
    Q_OBJECT
public:
    /** \brief Constructor
     *
     * \param name name of the sensor.
     * \param id database id of the sensor.
     * \param pin GPIO pin number.
     * \param interval time (in seconds) to pause between querying the sensor.
     */
    explicit HPCRainGauge( const QString& name, quint32 id, quint8 pin, quint16 interval )
        :HPCSensor(TSensorType::HPCRainGauge,name,id,pin), m_Interval(interval) {}
    /** \brief Destructor.
     */
    virtual ~HPCRainGauge() {}

    /** Get the interval time to count the ticks from the sensor.
     *
     * \return interval time in seconds.
     */
    inline quint16 Interval()
        { return m_Interval; }

    /** \brief Get class with content as printable string.
     *
     * \return string
     */
    QString asString() const;

private:
    quint16 m_Interval;
};

QDataStream& operator<< ( QDataStream& os, HPCRainGauge& s );

class HPCWindVane : public HPCSensor
{
    Q_OBJECT
public:
    /** \brief Constructor
     *
     * \param name name of the sensor.
     * \param id database id of the sensor.
     * \param channel The SPI channel of the connected mcp3008.
     * \param pin Inputpin of the mcp3008.
     */
    explicit HPCWindVane( const QString& name, quint32 id, quint8 channel, quint8 pin )
        :HPCSensor(TSensorType::HPCWindVane,name,id,pin), m_Channel(channel) {}
    /** \brief Destructor.
     */
    virtual ~HPCWindVane() {}

    /** \brief Get the SPI channel.
     *
     * \return The SPI channel (0/1).
     */
    inline quint8 Channel() const
      { return m_Channel; }

    /** \brief Get the direction in degrees.
     *
     * \return The direction in degrees.
     */
    float Degrees();

    /** \brief Get the direction as string.
     *
     * \return The direction as string ("N","NNE",NE",...).
     */
    QString dirString();

    /** \brief Get class with content as printable string.
     *
     * \return string
     */
    virtual QString asString() const;

private:
    const quint8 m_Channel; /**<  SPI channel */
};

QDataStream& operator<< ( QDataStream& os, HPCWindVane& s );

class HPCBarometer : public HPCSensor
{
    Q_OBJECT
public:
    static const double SEA_LEVEL_PRESSURE;
    static const double ALT_EXP;

    /** \brief Constructor
     *
     * \param name name of the sensor.
     * \param id database id of the sensor.
     * \param i2caddr the address on the i2c-bus.
     */
    explicit HPCBarometer( const QString& name, quint32 id, quint8 i2caddr )
        : HPCSensor(TSensorType::HPCBarometer,name,id,i2caddr) {}
    /** \brief Destructor.
     */
    virtual ~HPCBarometer() {}

    /** \brief Altitude in meters.
     * Given a pressure in kPa, such as returned from getBoth(),
     * getRelativeAltitude() returns an altitude in meters based
     * on a mean sea level pressure of 101.325 kPa.
     */
    static int getRelativeAltitude( float pressure );
    /** \brief Given a height in meters, returns a mean pressure in kPa.
     */
    static float getMeanPressure( int height );
};

QDataStream& operator<< ( QDataStream& os, HPCBarometer& s );

#endif // HPCSENSORS_H
